package com.clover.framework.net;

import com.alibaba.fastjson.JSON;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.CollectionUtils;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.io.*;
import java.net.*;
import java.security.cert.X509Certificate;
import java.util.List;
import java.util.Map;
import java.util.zip.GZIPInputStream;

/**
 * HttpHelper
 * @Author masl - 2018/11/26 13:07
 */
public class HttpHelper {
    /**
     * 向指定URL发送GET方法的请求
     */
    public static String sendGet(String url) {
        HttpItem item = new HttpItem().setURL(url);
        return HttpHelper.sendGet(item).getHtml();
    }

    /**
     * 向指定URL发送GET方法的请求
     */
    public static String sendGet(String url,String encoding) {
        HttpItem item = new HttpItem().setURL(url);
        if (StringUtils.isNotEmpty(encoding))
            item.setEncoding(encoding);
        return HttpHelper.sendGet(item).getHtml();
    }

    /**
     * 向指定URL发送GET方法的请求
     * @param item 发送请求的 参数[url=home.php?mod=space&uid=3039]@return[/url] URL 所代表远程资源的响应结果
     */
    public static HttpResult sendGet(HttpItem item) {
        HttpResult result = new HttpResult();
        String html ="";
        BufferedReader in = null;
        BufferedOutputStream out = null;
        try {
            String urlNameString = "";
            if (item.getURL().startsWith("http")) {
                urlNameString = item.getURL();
            } else {
                urlNameString = "http://" + item.getURL();
            }
            //请求参数
            String params = getReqParams(item);

            Proxy proxy = null;
            if (StringUtils.isNotEmpty(item.getProxyIp()) && item.getProxyPort() != null) {
                SocketAddress address = new InetSocketAddress(item.getProxyIp(), item.getProxyPort());
                proxy = new Proxy(Proxy.Type.HTTP, address);
            }

            URL realUrl = new URL(urlNameString + "?" + params);
            // 打开和URL之间的连接
            URLConnection conn = proxy == null ? realUrl.openConnection() : realUrl.openConnection(proxy);
            // 设置通用的请求属性
            conn.setRequestProperty("Accept", item.getAccept());
            conn.setRequestProperty("Content-Encoding", item.getContentEncoding());
            conn.setRequestProperty("C1onnection", item.getConnection());
            conn.setRequestProperty("User-Agent", item.getUserAgent());
            conn.setRequestProperty("Referer", item.getReferer());
            conn.setRequestProperty("Cookie", item.getCookie());
            conn.setRequestProperty("Host", item.getHost());
            //conn.setRequestProperty("encoding", item.getEncoding());
            //conn.setRequestProperty("Content-Type", item.getContentType());
            if (item.getHeader() != null && item.getHeader().size() > 0) {
                for (Map.Entry<String, String> entry : item.getHeader().entrySet()) {
                    /*if (entry.getKey().equalsIgnoreCase("Content-Encoding"))
                        ContentEncoding = entry.getValue();*/
                    conn.setRequestProperty(entry.getKey(), entry.getValue());
                }
            }
            // 建立实际的连接
            conn.connect();

            trustAllHosts();
            // 打开和URL之间的连接
            HttpURLConnection httpConn = proxy == null ? (HttpURLConnection) realUrl.openConnection() : (HttpURLConnection) realUrl.openConnection(proxy);

            result.setResposeCode(httpConn.getResponseCode());
            result.setResposeMessage(httpConn.getResponseMessage());

            // 获取所有响应头字段
            Map<String, List<String>> map = conn.getHeaderFields();
            // 遍历所有的响应头字段
            for (String key : map.keySet()) {
                System.out.println(key + "--->" + map.get(key));
            }
            //取cookie
            result.setCookie(getRespCookie(conn));

            String line;
            // 定义 BufferedReader输入流来读取URL的响应
            if (item.getContentEncoding().equals("gzip")) {
                in = new BufferedReader(new InputStreamReader(new GZIPInputStream(conn.getInputStream()), item.getEncoding()));
            } else {
                in = new BufferedReader(new InputStreamReader(
                        conn.getInputStream(), item.getEncoding()));
            }

            line = "";
            while ((line = in.readLine()) != null) {
                html += line;
            }
        } catch (Exception e) {
            System.out.println("发送GET请求出现异常！" + e);
            e.printStackTrace();
        }
        // 使用finally块来关闭输入流
        finally {
            try {
                if (in != null) {
                    in.close();
                }
            } catch (Exception e2) {
                e2.printStackTrace();
            }
        }
        result.setHtml(html);

        return result;
    }

    /**
     * 向指定 URL 发送POST方法的请求
     * @param url
     * @param params
     * @return
     */
    public static String sendPost(String url, Map<String, Object> params) {
        HttpItem item = new HttpItem()
                .setURL(url)
                .setParams(params);
        return HttpHelper.sendPost(item).getHtml();
    }

    /**
     * 向指定 URL 发送POST方法的请求
     * @param item 发送请求的 参数
     * @return 所代表远程资源的响应结果
     */
    public static HttpResult sendPost(HttpItem item) {
        HttpResult result = new HttpResult();
        String html ="";
        OutputStreamWriter out = null;
        BufferedReader in = null;
        try {
            String urlNameString = "";
            if (item.getURL().startsWith("http")) {
                urlNameString = item.getURL();
            } else {
                urlNameString = "http://" + item.getURL();
            }
            //请求参数
            String pstData = "";
            if (!CollectionUtils.isEmpty(item.getParams())) {
                pstData = JSON.toJSONString(item.getParams());
            }

            Proxy proxy = null;
            if (StringUtils.isNotEmpty(item.getProxyIp()) && item.getProxyPort() != null) {
                SocketAddress address = new InetSocketAddress(item.getProxyIp(), item.getProxyPort());
                proxy = new Proxy(Proxy.Type.HTTP, address);
            }

            URL realUrl = new URL(urlNameString);

            trustAllHosts();
            // 打开和URL之间的连接
            HttpURLConnection conn = proxy == null ? (HttpURLConnection) realUrl.openConnection() : (HttpURLConnection) realUrl.openConnection(proxy);
            // 发送POST请求必须设置如下两行
            conn.setDoOutput(true);
            conn.setDoInput(true);
            // 设置通用的请求属性
            conn.setRequestProperty("accept", item.getAccept());
            conn.setRequestProperty("connection", item.getConnection());
            conn.setRequestProperty("user-agent", item.getUserAgent());
            conn.setRequestProperty("Referer", item.getReferer());
            conn.setRequestProperty("Cookie", item.getCookie());
            conn.setRequestProperty("Host", item.getHost());
            conn.setRequestProperty("Content-Type", item.getContentType());

            if (item.getHeader() != null && item.getHeader().size() > 0) {
                for (Map.Entry<String, String> entry : item.getHeader().entrySet()) {
                    /*if (entry.getKey().equalsIgnoreCase("Content-Encoding"))
                        ContentEncoding = entry.getValue();*/
                    conn.setRequestProperty(entry.getKey(), entry.getValue());
                }
            }

            // 获取URLConnection对象对应的输出流
            out = new OutputStreamWriter(conn.getOutputStream(), "UTF-8"); // utf-8编码
            //参数是键值队  , 不以"?"开始
            out.write(pstData);
            // flush输出流的缓冲
            out.flush();

            HttpURLConnection httpConn = (HttpURLConnection) conn;
            result.setResposeCode(httpConn.getResponseCode());
            result.setResposeMessage(httpConn.getResponseMessage());

            //取cookie
            result.setCookie(getRespCookie(conn));

            // 定义BufferedReader输入流来读取URL的响应
            in = new BufferedReader(
                    new InputStreamReader(conn.getInputStream()));
            String line;
            while ((line = in.readLine()) != null) {
                html += line;
            }
        } catch (Exception e) {
            System.out.println("发送 POST 请求出现异常！" + e);
            e.printStackTrace();
        }
        //使用finally块来关闭输出流、输入流
        finally {
            try {
                if (out != null) {
                    out.close();
                }
                if (in != null) {
                    in.close();
                }
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
        result.setHtml(html);
        return result;
    }

    /**
     * 取请求参数
     * @param item
     * @return
     */
    private static String getReqParams(HttpItem item){
        String params = "";
        if (item.getParams().size() > 0) {
            String op = "";
            for (String key : item.getParams().keySet()) {
                params += op + key + "=" + item.getParams().get(key);
                op = "&";
            }
        }
        return params;
    }
    /**
     * 取 cookie
     * @param conn
     * @return
     */
    private static String getRespCookie(URLConnection conn){
        //取cookie
        String key = null;
        String cookies = "";
        for (int i = 1; (key = conn.getHeaderFieldKey(i)) != null; i++) {
            if (key.equalsIgnoreCase("set-cookie")) {
                String val = conn.getHeaderField(i);
                val = val.substring(0, val.indexOf(";"));
                cookies += val + ";";
            }
        }
        return cookies;
    }

    private static void trustAllHosts() {
        TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() {
            public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                return new java.security.cert.X509Certificate[]{};
            }

            public void checkClientTrusted(X509Certificate[] chain, String authType) {
            }

            public void checkServerTrusted(X509Certificate[] chain, String authType) {
            }
        }};
        try {
            SSLContext sc = SSLContext.getInstance("TLS");
            sc.init(null, trustAllCerts, new java.security.SecureRandom());
            HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        String url = "http://haijia.xuechebu.com:8008/KM2/ClYyCars2?ipaddress=192.168.1.75&ossdk=27&os=an&filters%5Bxnsd%5D=2001&appversion=4.2.8&filters%5Bxxzh%5D=51613896&version=4.2.8&filters%5Byyrq%5D=2018%E5%B9%B411%E6%9C%8826%E6%97%A5&filters%5Bjlcbh%5D=&xxzh=51613896&filters%5BtrainType%5D=&imei=0CD6D77DB125656206B3308500EB7443&osversion=8.1.0";
        HttpItem item = new HttpItem()
                .setURL(url)
                .setProxyIp("110.52.235.167")
                .setProxyPort(9999)
                .setCookie("JX_LoginOn=tHuIebKocq4joXX/W+I7WUr+Wusvt8ewMboCCJ16XDbjdl3WT6lP1HBuZMfmLtBWqJ1DaxQtJ/8imKh/NAgVNOiCE+zktRaQ8M/+7iZdBjRQzd9+q3ytjnzx2aULiPmH6s97dpDf5FVos4xsQ7Roub1VbHE7TaHpz8LvFKYBipQjtDYdIWsdbwQk1j9CERk1cderfZ16oblg+lZFEty41cf9S/o2GlbWIZoKauiHj+wov8GuuFpEZMiXFB+ha42yjdZNIiyxAAmu3QK0O+JY+kccsj8evdg6rhv4WHSKT47TeP+FI9A/wnOEi0kbRyyhlxcpUIB7XUrEeVmw97NGCokxrPgkkDKcQjJe73KQtSdBg1zuXCuAAUrNUn2nQSrflxcpUIB7XUqIb/2ZDzqwi6M7XtNNp5c9; yunsuo_session_verify=c36cecd298cb324e12e3d40a3a60bf1a; Webapi_LoginOn=mPP8hMEy3A16OVujh8nwhCZAPKC2n855djwGPh6aYjUM8BDSBeXCSpLappU7axAZdYNLFj5WyKPubfWnBIlcx6IfOHow2+Dkl6oli13TjDY18zUYA3H+ebXkJS9plecD8M/+RdTj15saaNl0cootrejIAVZr3Xs8nx16pKvRtwlLype7niWa9Tb9Xj583GS4wmVVOxqR4NZNM4SdU7lDssS3b/XOQS1M38oTdus0JIHTsfky7qKySWhCznuMEhCvJycHaHDaNnnfuB0WPoqleb/0WH4hTe72gYbaAy2GFlXhaS8nsnQzIGVp0c4fTm9IGSjBzIIttU8xCxthjhvld3bUPhWnQQaD+QRW6Ghi/sbyXrRbGqWXwCqJnnf5rF4RAeSEvo+zHaBLzkRcXeOxz4hoJphzPSkAjB9f6FZfhUldUPceHIKxrhyH4VsHOiWtF+TdSDXjEEEzb1gpAFHeNuk9yYJ5JqDd3J3h3aJ95RoVo6AEMjBeq5i21C9JxA5soGEdJhmXwLSOt3BU3Vd1x24/NwzBL9Bl1vELRX8VtgZWLJnDottCWEvKl7ueJZr1wkc/yAPQ0MJ76f+BH0SM/5ym7KYsqhVLE9XNBYA62DD6vBSGcxADqGEqEOLjuzO0HeUTxT9hU9jHN/Vr0btJGD6dJw8XlgrGk8DYx6RO5Ks7T+pURq1OxExV5D0yY2+ZTTOEnVO5Q7JKn/sqFJOXheNywjCdnOFQuOj6yMdtmAFnWFi9yB9RjfIyMsKqtv35MhEXXH2XkTHv0vEvlCPeAnxJrHE9Cb9fswtR23prphmWKoMWOKNCdnwcvntmA2ewFaoguG54sv7v0vEvlCPeAnxJrHE9Cb9fswtR23prphl4atbUTarDZLLBWB6NhBTGFeRftet1xNBrfEnoE/iuRqm9XS1qoSnVHznKeq3CVIZh04KA2TxjbDdoVl9iq35+IDSwaqGrOv5LE2JdGs1m+THdHPWAkf7RquYRxaY7Hrmn1YpDnHUr5NSN5I+hnUX740qYn+6jqxh2glVqTmZyK8ecMv6byzw7wUcZv9NgQqpe+MtxK9fFwWm5Pv2TpxQdeQ2bSUfwmAnpMq2NeyK2wUNDdUg/GfNmriqY3cJ/kBpLype7niWa9el5iKRcf7tFh4Zo/+5N75UXQPgwu+CP63vBFN9y2U/fVTEgJl3YGHTy6S1uXuJ72/OxK85YybUqq/Rq6NAcrZUYwzNLdK5ur5+4NnLRnQFDy+cyAXcuzDYyXbhhKjskXAreIRij6hmkTe/mpaj7vi0GFVutIT4/hAO8Ts0Cn0Mqv/UfTqZ0ilSA/tsTMispfw==; yunsuo_session_verify=8872fce0d2f16b0f80eb41f32e8367cb");
        System.out.print("\n\n" + HttpHelper.sendGet(item).getHtml());

        String loginUrl = "http://haijia.xuechebu.com:8008/Student/setbadingstuinfo?password=abcd0328&jgid=115001&xybh=8000370920";
        item = new HttpItem()
                .setURL(loginUrl);
        System.out.print("\n\n" + HttpHelper.sendGet(item));
    }
}